<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>canvas | LOST FLY</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            body, #fm {
                width: 100%;
            }
        </style>
        <script>
            var ge = function(dm) {return document.querySelector(dm)};
            var ga = function(dm) {return document.querySelectorAll(dm)};
            window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
            window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
            window.coll = new Object();
            window.bingo = 0;
            window.coinNum = 0;
            var sit0;

            function audioFactory(path) {
                var audio = document.createElement("audio");
                audio.src = path;
                audio.loop = false;
                audio.autostart = false;
                return audio;
            }

            document.addEventListener("DOMContentLoaded", function() {

                var fm = ge("#fm");
                var cvs = ge("#mirro");

                var boom = new Image();
                boom.src = "img/boom.png";

                // 击中音效
                var bomAudio = audioFactory("img/boom.mp3");
                // 掠过音效
                var loseAudio = audioFactory("img/lose.mp3");
                // 坠毁音效
                var crashAudio = audioFactory("img/crash.mp3");
                // 子弹音效
                // var shotAudio = audioFactory("img/shot.mp3");
                // 金币音效
                var coinAudio = audioFactory("img/coin.mp3");
                // 唤醒音效
                var startAudio = audioFactory("img/start.mp3");
                // 背景音效
                var bgAudio = document.createElement("audio");
                bgAudio.src = "img/bg.mp3";
                bgAudio.loop = true;
                bgAudio.autostart = false;
                bgAudio.volum = 0.2;

                var context = cvs.getContext("2d");
                context.fillStyle = "#000000";
                var cvsWidth = 500;
                var cvsHeight = 300;
                context.fillRect(0, 0, cvsWidth, cvsHeight);

                // 击落数显示
                function lostNum(num) {
                    context.clearRect(cvsWidth - 100, 10, 100, 20);
                    context.fillStyle = "#000000";
                    context.fillRect(cvsWidth - 100, 10, 100, 20);
                    context.beginPath();
                    context.fillStyle = "white";
                    context.font = "16px Sans-Serif";
                    context.textBaseline = "top";
                    context.fillText("击落: "+num, cvsWidth - 100, 10);
                }
                setInterval(function() {
                    lostNum(window.bingo);
                }, 500)
                lostNum(window.bingo);
                // 金币数显示
                function coinNum(num) {
                    context.clearRect(cvsWidth - 100, 30, 100, 20);
                    context.fillStyle = "#000000";
                    context.fillRect(cvsWidth - 100, 30, 100, 20);
                    context.beginPath();
                    context.fillStyle = "yellow";
                    context.font = "16px Sans-Serif";
                    context.textBaseline = "top";
                    context.fillText("金币: "+num, cvsWidth - 100, 30);
                }
                setInterval(function() {
                    coinNum(window.coinNum);
                }, 500)
                coinNum(window.coinNum);

                var rocket = new Image();
                rocket.src = "img/rocket.png";
                rocket.style.margin = 0;
                var initH = 252;
                var initW = 250-24;
                var speed = 20;  // 移动速度
                var step = 3  // 步长
                var clock0;
                rocket.onload = function() {
                    context.drawImage(rocket, initW, initH);
                    states = {
                        "left": false,
                        "right": false,
                        "up": false,
                        "down": false
                    }
                    window.addEventListener("keydown", function(event) {
                        var e = event || window.event || arguments.callee.caller.arguments[0];
                        switch (e && e.keyCode) {
                            case 87:
                                states.down = false;
                                states.up = true;
                                break;
                            case 83:
                                states.up = false;
                                states.down = true;
                                break;
                            case 65:
                                states.right = false;
                                states.left = true;
                                break;
                            case 68:
                                states.right = true;
                                states.left = false;
                                break;
                            case 32:
                                setTimeout(function() {
                                    ctrlPlayer();
                                }, 1);
                                // ctrlBlt();
                                break;
                            case 79:
                                ctrlBlt();
                                break;
                        }
                    });
                    window.addEventListener("keyup", function(event) {
                        var e = event || window.event || arguments.callee.caller.arguments[0];

                        switch (e && e.keyCode) {
                            case 87: states.up = false;
                            case 83: states.down = false;
                            case 65: states.left = false;
                            case 68: states.right = false;
                            break;
                        }
                    });

                    var onoff = false;
                    var sit1;
                    var sit2;

                    // 火箭控制
                    function ctrlPlayer() {
                        if (onoff) {
                            window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
                            cancelAnimationFrame(clock0);
                            clearInterval(sit0);
                            onoff = false;
                            // 显示暂停字样
                            bgAudio.pause();
                            clearTimeout(sit1);  // 停止陨石
                            clearTimeout(sit2);  // 停止金币
                            context.clearRect(0, 0, 500, 300);
                            context.fillStyle = "#000";
                            context.fillRect(0, 0, 500, 300);
                            context.beginPath();
                            context.fillStyle = "#1E90FF";
                            context.font = "16px Sans-Serif";
                            context.textBaseline = "top";
                            context.fillText("暂 停 pause", 200, 120);
                        } else {
                            // 游戏开始
                            bgAudio.play();
                            onoff = true;
                            window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
                            startAudio.play();
                            context.clearRect(0, 0, 500, 300);
                            context.fillStyle = "#000";
                            context.fillRect(0, 0, 500, 300);
                            context.beginPath();
                            context.fillStyle = "#1E90FF";
                            context.font = "16px Sans-Serif";
                            context.textBaseline = "top";
                            context.fillText("开 始 start", 200, 120);
                            sit1 = setTimeout(function() {
                                context.clearRect(0, 0, 500, 300);
                                context.fillStyle = "#000";
                                context.fillRect(0, 0, 500, 300);
                            }, 1000);
                            function raf(timestamp) {
                                context.clearRect(initW, initH, 48, 48);
                                context.fillStyle = "#000000";
                                context.fillRect(initW, initH, 48, 48);
                                initH = states.up && initH >= 0 ? initH-step : (states.down && initH <= 252 ? initH+step : initH);
                                initW = states.left && initW >= 0 ? initW-step : (states.right && initW <= 460 ? initW+step : initW);
                                context.drawImage(rocket, initW, initH);
                                clock0 = requestAnimationFrame(raf);
                            }
                            clock0 = requestAnimationFrame(raf);

                            // 激活陨石运动
                            sit0 = setInterval(function() {
                                var W_Plus = Math.ceil(Math.random() * (500 - 48));
                                makeMarker(W_Plus);
                            }, 2000);
                            // 金币掉落
                            sit2 = setInterval(function() {
                                var W_Plus = Math.ceil(Math.random() * (500 - 32));
                                var H_Plus = Math.ceil(Math.random() * (300 - 32));
                                makeCoin(W_Plus, H_Plus);
                            }, 5000);
                        }
                    }

                    // 子弹轨迹
                    function ctrlBlt() {
                        if (onoff) {
                            var swapW = initW + 24;
                            var swapH = initH;
                            function blt(timestamp) {
                                context.clearRect(swapW-3, swapH, 6, 6);
                                context.fillStyle = "#000000";
                                context.fillRect(swapW-3, swapH, 6, 6);
                                delete window.coll[clock1];
                                context.beginPath();
                                context.fillStyle="#FF8C00";
                                swapH -= 2;
                                context.arc(swapW,swapH,3,0,Math.PI*2,true);
                                context.fill();
                                clock1 = requestAnimationFrame(blt);
                                window.coll[clock1] = {
                                    "x" : swapW,
                                    "y" : swapH
                                }
                                if (swapH <= 10) {
                                    context.clearRect(swapW-3, swapH-3, 6, 8);
                                    context.fillStyle = "#000000";
                                    context.fillRect(swapW-3, swapH-3, 6, 8);
                                    delete window.coll[clock1];
                                    cancelAnimationFrame(clock1);
                                }
                            }
                            var clock1 = requestAnimationFrame(blt);
                            // shotAudio.play();
                        }
                    }

                    // 金币出现
                    function makeCoin(W_Plus, H_Plus) {
                        var coin = new Image();
                        coin.src = "img/coin.png";
                        coin.style.margin = 0;
                        var slY = H_Plus;
                        var slX = W_Plus;
                        var swapCvsH = cvsHeight-32;
                        coin.onload = function() {
                            // 持续输出
                            function makerCoin() {
                                context.beginPath();
                                context.drawImage(coin, slX, slY);
                                // 检测是否捡起
                                if (initW >= (slX-32) && initW <= (slX + 32)) {
                                    if (initH >= (slY-32) && initH <= (slY + 32)) {
                                        cancelAnimationFrame(swap);
                                        coinAudio.play();  // 播放坠毁音效
                                        context.clearRect(slX, slY, 32, 32);
                                        context.fillStyle = "#000";
                                        context.fillRect(slX, slY, 32, 32);
                                        coinNum(++window.coinNum);
                                        return 0;
                                    }
                                }
                                swap = requestAnimationFrame(makerCoin);
                            }
                            var swap = requestAnimationFrame(makerCoin);
                            setTimeout(function() {
                                context.clearRect(slX, slY, 32, 32);
                                context.fillStyle = "#000";
                                context.fillRect(slX, slY, 32, 32);
                                cancelAnimationFrame(swap);
                            }, 5000);
                        };
                    }

                    // 标靶运动
                    function makeMarker(W_Plus) {
                        var satellite = new Image();
                        satellite.src = "img/satellite.png";
                        satellite.style.margin = 0;
                        var slY = 0;
                        var swapCvsH = cvsHeight-48;
                        satellite.onload = function() {
                            function marker(timestamp) {
                                var slX = W_Plus;
                                slY++;
                                context.clearRect(slX, slY, 48, 48);
                                context.fillStyle = "#000000";
                                context.fillRect(slX, slY, 48, 48);
                                context.beginPath();
                                context.drawImage(satellite, slX, slY);
                                clock2 = requestAnimationFrame(marker);
                                // 检测是否命中
                                setTimeout(function() {
                                    if (checkColl(slX, slY)) {
                                        context.clearRect(slX, slY, 48, 48);
                                        context.fillStyle = "#000000";
                                        context.fillRect(slX, slY, 48, 48);
                                        context.drawImage(boom, slX, slY);
                                        bomAudio.play();  // 播放击中音效
                                        setTimeout(function() {
                                            context.clearRect(slX, slY, 48, 48);
                                            context.fillStyle = "#000000";
                                            context.fillRect(slX, slY, 48, 48);
                                        }, 100);
                                        cancelAnimationFrame(clock2);
                                    }
                                    else if (slY >= swapCvsH) {
                                        context.clearRect(slX, slY, 48, 48);
                                        context.fillStyle = "#000000";
                                        context.fillRect(slX, slY, 48, 48);
                                        loseAudio.play();
                                        cancelAnimationFrame(clock2);
                                    }
                                }, 1);
                                // 检测是否碰撞
                                setTimeout(function() {
                                    if (initW >= (slX-48) && initW <= (slX + 48)) {
                                        if (initH >= (slY-48) && initH <= (slY + 48)) {
                                            clearInterval(sit0);  // 停止陨石
                                            clearTimeout(sit2);  // 停止金币
                                            crashAudio.play();  // 播放坠毁音效
                                            cancelAnimationFrame(clock0);
                                            context.clearRect(0, 0, 500, 300);
                                            context.fillStyle = "#000";
                                            context.fillRect(0, 0, 500, 300);
                                            context.beginPath();
                                            context.fillStyle = "white";
                                            context.font = "16px Sans-Serif";
                                            context.textBaseline = "top";
                                            context.fillText("GAME OVER", 200, 120);
                                            onoff = false;
                                            bgAudio.pause();
                                        }
                                    }
                                }, 1);
                            }
                            var clock2 = requestAnimationFrame(marker);
                        }
                    }

                    function checkColl(slX, slY) {
                        var i;
                        for (i in window.coll) {
                            var x = window.coll[i]["x"];
                            var y = window.coll[i]["y"];
                            if (y > slY && y < slY+48) {
                                if (x > slX && x < slX+48) {
                                    // 多进程消除
                                    setTimeout(function() {
                                        context.beginPath();
                                        context.clearRect(x-3, y-3, 6, 8);
                                        context.fillStyle = "#000000";
                                        context.fillRect(x-3, y-3, 6, 8);
                                        lostNum(++window.bingo);
                                    }, 1);
                                    cancelAnimationFrame(i);
                                    delete window.coll[i];
                                    return true;
                                }
                            }
                        }
                        return false;
                    }
                    
                }
            });
        </script>
    </head>

    <body>
        <div id="fm" style="margin:1em;">
            <canvas id="mirro" width="500", height="300">
                你们有没有 . . . 那个 . . . 支持 canvas 的浏览器 . . .
            </canvas>
        </div>
        <div style="margin-left:1em;">
            <h3>操作说明</h3>
            <p>先安空格开始游戏</p>
            <p>SPACE【空格】：开始/暂停</p>
            <p>a：左移</p>
            <p>w：上移</p>
            <p>s：下移</p>
            <p>d：右移</p>
            <p>o：发射一颗子弹</p>
        </div>
        <input type="text" />
        <!-- <audio id="ado" style="display:none;" loop="loop" volumevalue="0.1" autoplay="autoplay">
            <source src="img/bg.mp3" type="audio/mp3" />
        </audio>
        <script>
            document.getElementById("ado").volume = 0.15;
        </script> -->
    </body>
</html>